home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / src / Assemblers / 68kasm / codegen.c < prev    next >
C/C++ Source or Header  |  1995-07-26  |  5KB  |  179 lines

  1. /******************************************************************************
  2.  * $Id: codegen.c,v 1.1 1994/08/29 23:55:50 bmott Exp $
  3.  ******************************************************************************
  4.  *
  5.  *        CODE.C
  6.  *        Code Generation Routines for 68000 Assembler
  7.  *
  8.  *    Function: output()
  9.  *        Places the data whose size and value are specified onto
  10.  *        the output stream at the current location contained in
  11.  *        global varible loc. That is, if a listing is being
  12.  *        produced, it calls listObj() to print the data in the
  13.  *        object code field of the current listing line; if an
  14.  *        object file is being produced, it calls outputObj() to
  15.  *        output the data in the form of S-records. 
  16.  *
  17.  *        effAddr()
  18.  *        Computes the 6-bit effective address code used by the
  19.  *        68000 in most cases to specify address modes. This code
  20.  *        is returned as the value of effAddr(). The desired
  21.  *        addressing mode is determined by the field of the
  22.  *        opDescriptor which is pointed to by the operand
  23.  *        argument. The lower 3 bits of the output contain the
  24.  *        register code and the upper 3 bits the mode code. 
  25.  *
  26.  *        extWords()
  27.  *        Computes and outputs (using output()) the extension 
  28.  *        words for the specified operand. The generated
  29.  *        extension words are determined from the data contained
  30.  *        in the opDescriptor pointed to by the op argument and
  31.  *        from the size code of the instruction, passed in 
  32.  *        the size argument. The errorPtr argument is used to
  33.  *        return an error code by the standard mechanism. 
  34.  *
  35.  *     Usage: output(data, size)
  36.  *        int data, size;
  37.  *
  38.  *        effAddr(operand)
  39.  *        opDescriptor *operand;
  40.  *
  41.  *        extWords(op, size, errorPtr)
  42.  *        opDescriptor *op;
  43.  *        int size, *errorPtr;
  44.  *
  45.  *      Author: Paul McKee
  46.  *        ECE492    North Carolina State University
  47.  *
  48.  *        Date:    12/13/86
  49.  *
  50.  *   Copyright 1990-1991 North Carolina State University. All Rights Reserved.
  51.  *
  52.  ******************************************************************************
  53.  * $Log: codegen.c,v $
  54.  * Revision 1.1  1994/08/29  23:55:50  bmott
  55.  * Initial revision
  56.  *
  57.  *****************************************************************************/
  58.  
  59.  
  60. #include <stdio.h>
  61. #include "asm.h"
  62.  
  63. extern int loc;
  64. extern char pass2;
  65. extern FILE *listFile;
  66.  
  67. extern char listFlag;    /* True if a listing is desired */
  68. extern char objFlag;    /* True if an object code file is desired */
  69.  
  70.  
  71. output(data, size)
  72. int data, size;
  73. {
  74. /*    switch (size) {
  75.         case BYTE : printf("Output: Byte           %02X put into output stream at location %08X\n", data, loc); break;
  76.         case WORD : printf("Output: Word         %04X put into output stream at location %08X\n", data, loc); break;
  77.         case LONG : printf("Output: Longword %08X put into output stream at location %08X\n", data, loc); break;
  78.         default   : printf("OUTPUT: INVALID SIZE CODE!\n"); exit();
  79.         }  */
  80.     if (listFlag)
  81.         listObj(data, size);
  82.     if (objFlag)
  83.         outputObj(loc, data, size);
  84. }
  85.  
  86.  
  87. effAddr(operand)
  88. opDescriptor *operand;
  89. {
  90.     switch (operand->mode) {
  91.         case DnDirect    : return 0x00 | operand->reg; break;
  92.         case AnDirect    : return 0x08 | operand->reg; break;
  93.         case AnInd    : return 0x10 | operand->reg; break;
  94.         case AnIndPost    : return 0x18 | operand->reg; break;
  95.         case AnIndPre    : return 0x20 | operand->reg; break;
  96.         case AnIndDisp    : return 0x28 | operand->reg; break;
  97.         case AnIndIndex : return 0x30 | operand->reg; break;
  98.         case AbsShort    : return 0x38; break;
  99.         case AbsLong    : return 0x39; break;
  100.         case PCDisp    : return 0x3A; break;
  101.         case PCIndex    : return 0x3B; break;
  102.         case Immediate    : return 0x3C; break;
  103.         default        : printf("INVALID EFFECTIVE ADDRESSING MODE!\n"); exit (0);
  104.         }
  105. }
  106.  
  107.  
  108. extWords(op, size, errorPtr)
  109. opDescriptor *op;
  110. int size, *errorPtr;
  111. {
  112. int disp;
  113.  
  114.     switch (op->mode) {
  115.         case DnDirect    : 
  116.         case AnDirect    :         /* These modes take    */
  117.         case AnInd    :         /* no extension words.    */
  118.         case AnIndPost    : 
  119.         case AnIndPre    : break;
  120.         case AnIndDisp    : 
  121.         case PCDisp    : if (pass2) {
  122.                     disp = op->data;
  123.                     if (op->mode == PCDisp)
  124.                         disp -= loc;
  125.                     output(disp & 0xFFFF, WORD);
  126.                     if (disp < -32768 || disp > 32767)
  127.                         NEWERROR(*errorPtr, INV_DISP);
  128.                     }
  129.                   loc += 2;
  130.                   break;
  131.         case AnIndIndex : 
  132.         case PCIndex    : if (pass2) {
  133.                     disp = op->data;
  134.                     if (op->mode == PCIndex)
  135.                         disp -= loc;
  136.                     output(((op->size == LONG) ? 0x800 : 0)
  137.                            | (op->index << 12) | (disp & 0xFF), WORD);
  138.                     if (disp < -128 || disp > 127)
  139.                         NEWERROR(*errorPtr, INV_DISP);
  140.                     }
  141.                   loc += 2;
  142.                   break;
  143.         case AbsShort    : if (pass2) {
  144.                     output(op->data & 0xFFFF, WORD);
  145.                     if (op->data < -32768 || op->data > 32767)
  146.                         NEWERROR(*errorPtr, INV_ABS_ADDRESS);
  147.                     }
  148.                   loc += 2;
  149.                   break;
  150.         case AbsLong    : if (pass2)
  151.                     output(op->data, LONG);
  152.                   loc += 4;
  153.                   break;
  154.         case Immediate    : if (!size || size == WORD) {
  155.                     if (pass2) {
  156.                         output(op->data & 0xFFFF, WORD);
  157.                         if (op->data < -32768 || op->data > 32767)
  158.                             NEWERROR(*errorPtr, INV_16_BIT_DATA);
  159.                         }
  160.                     loc += 2;
  161.                     }
  162.                   else if (size == BYTE) {
  163.                     if (pass2) {
  164.                         output(op->data & 0xFF, WORD);
  165.                         if (op->data < -32768 || op->data > 32767)
  166.                             NEWERROR(*errorPtr, INV_8_BIT_DATA);
  167.                         }
  168.                     loc += 2;
  169.                     }
  170.                   else if (size == LONG) {
  171.                     if (pass2)
  172.                         output(op->data, LONG);
  173.                     loc += 4;
  174.                     }
  175.                   break;
  176.         default        : printf("INVALID EFFECTIVE ADDRESSING MODE!\n"); exit();
  177.         }
  178. }
  179.